/*
 * BaseStrategy.cpp
 *
 *  Created on: 2021��7��16��
 *      Author: root
 */

#include "BaseStrategy.h"

BaseStrategy::BaseStrategy() = default;

BaseStrategy::BaseStrategy(DataEngine *p_engine) {
    this->p_engine = p_engine;
}

BaseStrategy::~BaseStrategy() {
    if (this->p_engine != nullptr) {

        if (this->lastMd != nullptr) {
            delete[] this->lastMd;
            this->lastMd = nullptr;
        }
        if (this->preMd != nullptr) {
            delete[] this->preMd;
            this->preMd = nullptr;
        }
    }
}

void BaseStrategy::preQryProcessSymbolStatus(char status, const string &enterTime) {

    if (status == '2') {
        if (!p_engine->isTrading) {
            p_engine->isTrading = true;
        }
        //SPDLOG_INFO("{} is be trading now", this->strategyName);
    }
    if (status == '3') {
    }
    if (status == '5') {
    }

    if (status == '1') {
    }
    if (status == '6') {
    }
}

void BaseStrategy::preProcessSymbolStatus(char status, const string &enterTime) {

    this->processStatusChanged(status, enterTime);
    if (status == '2') {
        processBeginAction(enterTime);
    }
    if (status == '3') {
        processCallAction(enterTime);
    }
    if (status == '5') {
        processCallFinishAction(enterTime);
    }

    if (status == '1') {
        if (strcmp(enterTime.c_str(), "10:15:00") == 0 || strcmp(enterTime.c_str(), "11:30:00") == 0) {
            this->processPauseAction(enterTime);
        }
    }
    if (status == '6') {
        this->preProcessClose(this->lastMd[0]);
    }
}

void BaseStrategy::preProcessMD(const TickDataHf &md) {

    if (!this->isActive || md.ask_price <= md.bid_price) {
        return;
    }

    auto it = std::find(this->contractCodes.begin(), contractCodes.end(), md.instrument_id);
    if (it == contractCodes.end()) {
        throw std::runtime_error("contractCode not found");
    }

    long index = std::distance(this->contractCodes.begin(), it);

    if (index >= this->contractCodes.size()) {
        throw std::runtime_error("Invalid index");
    }

    if (index == 0) {
        mdTimes++;
    }

    if (preMd[index].last_price > 0) {
        md.lastVol = md.volume - preMd[index].volume;
        md.lastAmount = md.amount - preMd[index].amount;
        if (md.lastVol > 0) {
            md.lastAvgPrice = md.lastAmount / md.lastVol / multiple;
        } else {
            md.lastAvgPrice = md.last_price;
        }
    }

    lastMd[index] = md;

    processMD(md, index);

    preMd[index] = md;
}

string BaseStrategy::contractToString() {
    string s;
    size_t size = this->contractCodes.size();
    for (int i = 0; i < size; i++) {
        s.append(this->contractCodes[i]);
        if (i < size - 1) {
            s.append("|");
        }
    }
    return s;
}

int BaseStrategy::getPreAskPriceCount(const TickDataHf &md, double price) const {
    int sum = 0;

    for (int i = 0; i < 5; i++) {

        if (price > (md.ask_prices[i] - 0.1 * minMove)) {
            sum = sum + md.ask_volumes[i];
        }
    }

    return sum;
}

double BaseStrategy::getPreAskVolPrice(const TickDataHf &md, int count) const {

    uint32_t sum = 0;

    for (int i = 0; i < 5; i++) {
        sum = sum + md.ask_volumes[i];
        if (sum >= count) {
            if (i > 0) {
                return md.ask_prices[i] - minMove;
            } else {
                return md.ask_prices[0];
            }
        }
    }

    return md.ask_prices[4];
}

double BaseStrategy::getAftAskVolPrice(const TickDataHf &md, int count) {

    int sum = 0;

    for (int i = 0; i < 5; i++) {
        sum = sum + md.ask_volumes[i];
        if (sum > count) {
            return md.ask_prices[i];
        }
    }

    return md.ask_prices[4];
}

int BaseStrategy::getPreBidPriceCount(const TickDataHf &md, double price) const {
    int sum = 0;

    for (int i = 0; i < 5; i++) {

        if (price < (md.bid_prices[i] + 0.1 * minMove)) {
            sum = sum + md.bid_volumes[i];
        }
    }

    return sum;
}

double BaseStrategy::getPreBidVolPrice(const TickDataHf &md, int count) const {
    unsigned int sum = 0;

    for (int i = 0; i < 5; i++) {
        sum = sum + md.bid_volumes[i];
        if (sum >= count) {
            if (i > 0) {
                return md.bid_prices[i] + minMove;
            } else {
                return md.bid_prices[0];
            }
        }
    }

    return md.bid_prices[4];
}

double BaseStrategy::getAftBidVolPrice(const TickDataHf &md, int count) {
    int sum = 0;

    for (int i = 0; i < 5; i++) {
        sum = sum + md.bid_volumes[i];
        if (sum > count) {

            return md.bid_prices[i];
        }
    }

    return md.bid_prices[4];
}

void BaseStrategy::initStrategy(DataEngine *p_engine, const std::string &params) {
    this->strategyId = p_engine->getNextStrategyId();
    this->p_engine = p_engine;
    this->loadParams(params);
    init();
    p_engine->addStrategy(strategyId, this);
    allParams["strategyId"] = strategyId;
}

void BaseStrategy::preProcessClose(const TickDataHf &md) {

    this->processClose(md);
}

void processOrderCxl(EES_OrderCxled *p_cxl) {
}

string BaseStrategy::getIsRun() const {
    if (this->isActive) {
        return "YES";
    } else {
        return "NO";
    }
}

string BaseStrategy::getBaseParams() const {
    return this->strategyName;
}


void BaseStrategy::preProcessOrder(const OrderData &order) {

    if (order.eventType > 0) {
        auto it = unFinishOrders.find(order.clientToken);
        if (it != unFinishOrders.end()) {
            if (order.eventType == 1) {
                it->second.m_Account = order.m_Account;
                it->second.inputPrice = order.inputPrice;
                it->second.eesMarketToken = order.eesMarketToken;
                it->second.remainVol = order.remainVol;

            } else if (order.eventType == 2) {
                it->second.eesMarketToken = order.eesMarketToken;
                processMarketOrder(it->second);
                ++p_engine->informationMap[it->second.contractCode];
            } else if (order.eventType == 3) {
                it->second.dealVol = order.dealVol;
                it->second.sumDealVol = it->second.sumDealVol + order.dealVol;
                it->second.sumDealPrice = it->second.sumDealPrice + order.dealPrice * order.dealVol;
                it->second.dealPrice = order.dealPrice;
                it->second.remainVol = it->second.remainVol - order.dealVol;
                this->preProcessOrderDeal(it->second);
                if (it->second.remainVol == 0) {
                    preProOrderDealFinish(it->second);
                    unFinishOrders.erase(it);

                }

            } else if (order.eventType == 4) {
                if(it->second.sumDealVol>0)
                {
                    preProOrderDealFinish(it->second);
                }
                preProcessOrderCxl(it->second);
                unFinishOrders.erase(it);


            } else {
                SPDLOG_ERROR("EVENTTYPE IS ERROR");
            }
        } else {
            //SPDLOG_ERROR("ERROR NOT find order clientId = {} type = {}", order.clientToken, order.eventType);
            //unFinishOrders.insert(pair<EES_ClientToken, OrderData>(order.clientToken, OrderData(order)));
        }
    } else {
        auto it = unFinishOrders.find(order.clientToken);
        if (it != unFinishOrders.end()) {
            if (order.eventType == -1) {
                this->errorId=order.m_ReasonCode;
                SPDLOG_INFO("ORDERREJECT:{} clientToken = {}  rejectReason = {} order = {}", getBaseParams(),
                            order.clientToken,
                            order.m_ReasonCode,
                            it->second);
                this->unFinishOrders.erase(it);

            } else if (order.eventType == -2) {
                this->errorId=order.m_ExchangeErrorId;
                if (order.m_ExchangeErrorId == 26) {
                    this->processMarketReject(it->second);
                }
                SPDLOG_INFO("MARKETREJECT:{} clientToken = {}  rejectReason = {},rejectText = {},order = {}",
                            getBaseParams(),
                            order.clientToken,
                            order.m_ReasonCode,
                            order.m_ReasonText,
                            it->second);

                this->unFinishOrders.erase(it);
                //order.isFinished = true;
            } else if (order.eventType == -3) {
                this->errorId=order.eventType;
                SPDLOG_INFO("OrderError: {} {} {}", this->getBaseParams(), order.clientToken,
                            it->second);
                unFinishOrders.erase(it);
                //order.isFinished = true;

            } else if (order.eventType == -4) {
                unsigned int reason = order.m_ReasonCode;
                this->errorId=reason;
                it->second.isCanceled = false;
                if (reason == 33) {
                }
                SPDLOG_INFO("CANCELReject: {} {} {}", this->getBaseParams(), order.clientToken,
                            it->second);

            } else {
                SPDLOG_INFO("EVENTTYPE IS ERROR");
            }
        } else {
            // SPDLOG_ERROR("{} not in this strategy",order.clientToken);
        }
    }
}


void BaseStrategy::init() {
    size_t size = contractCodes.size();

    lastMd = new TickDataHf[size];
    preMd = new TickDataHf[size];
    positions.reserve(size);
    for (int i = 0; i < size; ++i) {

        json j = nlohmann::json{
                {"contractCode", contractCodes[i]},
                {"bkTdVol",      0},
                {"bkYdVol",      0},
                {"skTdVol",      0},
                {"skYdVol",      0},
                {"sumBkPrice",   0},
                {"sumSkPrice",   0}
        };
        positions.emplace_back(j.dump());

    }

    auto it = this->p_engine->contractMap.find(contractCodes[0]);
    if (it != p_engine->contractMap.end()) {
        this->product_id = it->second.at("product_id").get<string>();
        this->exchangeId = it->second.at("exchange_id").get<char>();
        this->minMove = it->second.at("price_tick").get<double>();
        this->multiple = it->second.at("multiple").get<double>();
        this->expire = it->second.at("expire").get<int>();
        this->trading_time = it->second.at("trading_time").get<short>();
        jsonParams["exchangeId"] = exchangeId;
        jsonParams["minMove"] = minMove;
        jsonParams["multiple"] = multiple;
        jsonParams["expire"] = expire;
        jsonParams["trading_time"] = trading_time;
    } else {
        SPDLOG_ERROR("{} contract is error", contractCodes[0]);
        this->isActive = false;
    }
    if (strategyName.empty()) {
        strategyName = getClassName().append("|").append(product_id).append("_").append(p_engine->getMaxStrategyId());
    }
}

void BaseStrategy::preProcessOrderCxl(const OrderData &field) {
    p_engine->informationMap[field.contractCode]++;
    this->processOrderCxl(field);
}


void BaseStrategy::preProcessOrderDeal(const OrderData &field) {
    auto it = std::find(this->contractCodes.begin(), contractCodes.end(), field.contractCode);
    if(it!=contractCodes.end())
    {
        this->dealVol += field.dealVol;
        size_t index = std::distance(this->contractCodes.begin(), it);
        switch (field.side) {
            case EES_SideType_open_long:
                this->positions[index].bkTdVol += field.dealVol;
                this->positions[index].sumBkPrice += field.dealPrice * field.dealVol;
                break;
            case EES_SideType_open_short:
                this->positions[index].skTdVol += field.dealVol;
                this->positions[index].sumSkPrice += field.dealPrice * field.dealVol;
                break;
            case EES_SideType_close_today_long:
                this->positions[index].bkTdVol -= field.dealVol;
                this->positions[index].sumBkPrice -= field.dealPrice * field.dealVol;
                break;
            case EES_SideType_close_today_short:
                this->positions[index].skTdVol -= field.dealVol;
                this->positions[index].sumSkPrice -= field.dealPrice * field.dealVol;
                break;
            case EES_SideType_close_ovn_long:
                this->positions[index].bkYdVol -= field.dealVol;
                this->positions[index].sumBkPrice -= field.dealPrice * field.dealVol;
                break;
            case EES_SideType_close_ovn_short:
                this->positions[index].skYdVol -= field.dealVol;
                this->positions[index].sumSkPrice -= field.dealPrice * field.dealVol;
                break;
            default:
                // Handle unexpected side type
                SPDLOG_ERROR("Unexpected side type: {}", static_cast<int>(field.side));
                return;
        }
        if (positions[index].getBkVol() == 0) {
            sumProfit -= positions[index].sumBkPrice;
            positions[index].sumBkPrice = 0;
        }
        if (positions[index].getSkVol() == 0) {
            sumProfit += positions[index].sumSkPrice;
            positions[index].sumSkPrice = 0;
        }
        this->processDeal(field);
    }
    else
    {
        SPDLOG_ERROR("{} not in contractCodes", field);
        this->processDeal(field);
        return;
    }

}

/*void BaseStrategy::orderInsert(const string &contractCode, double price, unsigned int vol, char flag) {
    if (this->checkLimitOrder(contractCode, price, vol)) {
        ReqOrderField temp(exchangeId, contractCode, formatPrice(price), vol, flag, p_engine->getNextToken());
        unFinishOrders.insert(make_pair(temp.enterOrder.m_ClientOrderToken, OrderData(temp)));
        p_engine->reqOrderInsert(temp);
    }
}*/
void
BaseStrategy::orderInsert(const std::string &contractCode, double price, int vol, char flag, int basketId) {
    if (this->checkLimitOrder(contractCode, price, vol)) {
        temp.initByOrder(exchangeId, contractCode, formatPrice(price), vol, flag, p_engine->getNextToken(), basketId);
        unFinishOrders.insert(make_pair(temp.enterOrder.m_clientToken,
                                        OrderData(exchangeId, contractCode, formatPrice(price), vol, flag,
                                                  temp.enterOrder.m_clientToken)));
        p_engine->udpOrderHandel(temp);
    }
}


void BaseStrategy::orderInsertEx(const string &contractCode, double price,  int vol, char flag) {
    long index = (std::find(this->contractCodes.begin(), contractCodes.end(), contractCode) - contractCodes.begin());

    if (flag == EES_SideType_close_long) {
        if (vol > this->positions[index].getBkVol()) {

            this->orderInsert(contractCode, price, positions[0].bkTdVol,
                              EES_SideType_close_today_long);

            this->orderInsert(contractCode, price, positions[0].bkYdVol, EES_SideType_close_ovn_long);
        } else {
            if (positions[index].bkYdVol == 0) {
                this->orderInsert(contractCode, price, vol, EES_SideType_close_today_long);
            }
            if (positions[index].bkYdVol > 0) {
                if (vol <= positions[index].bkYdVol) {
                    this->orderInsert(contractCode, price, vol, EES_SideType_close_ovn_long);
                } else {
                    this->orderInsert(contractCode, price, positions[index].bkYdVol,
                                      EES_SideType_close_ovn_long);
                    this->orderInsert(contractCode, price, vol - positions[index].bkYdVol,
                                      EES_SideType_close_today_long);
                }
            }
        }
    } else if (flag == EES_SideType_close_short) {
        if (vol > this->positions[index].getSkVol()) {

            orderInsert(contractCode, price, positions[0].skTdVol, EES_SideType_close_today_short);

            orderInsert(contractCode, price, positions[0].skYdVol, EES_SideType_close_ovn_short);
        } else {
            if (positions[index].skYdVol == 0) {
                this->orderInsert(contractCode, price, vol, EES_SideType_close_today_short);
            }
            if (positions[index].skYdVol > 0) {
                if (vol <= positions[index].skYdVol) {
                    this->orderInsert(contractCode, price, vol, EES_SideType_close_ovn_short);
                } else {
                    this->orderInsert(contractCode, price, positions[index].skYdVol,
                                      EES_SideType_close_ovn_short);
                    this->orderInsert(contractCode, price, vol - positions[index].skYdVol,
                                      EES_SideType_close_today_short);
                }
            }
        }
    } else {
        if (isBeforeLDate) {
            if (this->dealVol < dealLimit) {
                orderInsert(contractCode, price, vol, flag);
            } else {
  /*              static bool executed = false;
                if (!executed) {
                    // 你的代码逻辑
                    SPDLOG_INFO("{} is max than {}", dealVol, dealLimit);
                    executed = true;
                }*/
            }
        } else {
            //SPDLOG_INFO("{} is begin",expire);
        }

    }
}


void BaseStrategy::checkDate() {


    for (const string &contractCode: this->contractCodes) {
        auto it = p_engine->contractMap.find(contractCode);
        if (it != p_engine->contractMap.end()) {
            try {
                if (it->second.contains("expire")) {
                    int tmpExpire = it->second["expire"].get<int>();
                    if (tmpExpire < expire) {
                        expire = tmpExpire;
                        jsonParams["expire"]=expire;
                    }
                }
            } catch (const std::exception &e) {
                // 处理异常，例如记录日志或跳过当前项
                cout<<e.what() << endl;
            }
        }
    }

    if (expire > this->limitDate) {
        this->isBeforeLDate = true;
        cout << this->strategyName << "expire = " << expire << "  can open position" << endl;
    } else {
        cout << this->strategyName << "expire = " << expire << "  can not open position" << endl;
    }
}

void BaseStrategy::orderCancel(const OrderData &order) {
    if (order.eesMarketToken > 0) {
        if (!order.isCanceled) {
            temp.initByCancel(order.clientToken, order.eesMarketToken);
            p_engine->udpOrderHandel(temp);
            order.isCanceled = true;
        }
    } else {

        auto it = unFinishOrders.find(order.clientToken);
        if (it != unFinishOrders.end()) {
            it->second.noIdTimes = ++it->second.noIdTimes;
            if (it->second.noIdTimes > 5) {
                Event tmpEvent;
                tmpEvent.order.initByOrderFailed(order.contractCode,
                                                 order.inputPrice, order.vol,
                                                 order.side,
                                                 order.clientToken);
                p_engine->addEvent(tmpEvent);
                SPDLOG_ERROR("未有订单号 {} -> {}", this->getBaseParams(), order.clientToken, order);
            }
        }
    }
}

double BaseStrategy::formatPrice(double price) const {

    return round(price / minMove) * minMove;
}

bool BaseStrategy::checkLimitOrder(const string &contractCode, double price, int vol) {
    if (this->p_engine->informationMap[contractCode] <= 3900) {
        if (vol > 0&&price>0) {
            return true;
        }
    }
    return false;
}

bool BaseStrategy::checkFakOrder(const string &contractCode, double price, int vol) {
    if (this->exchangeId == EES_ExchangeID_ine) {
        if (this->p_engine->informationMap[contractCode] <= 1500) {
            if (vol > 0) {
                return true;
            } else {
                printf("vol = " + vol);
                return false;
            }
        }
    } else if (this->exchangeId == EES_ExchangeID_shfe) {
        if (vol > 0) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }

    this->stop();
    return false;
}

bool BaseStrategy::isIntraderTime() {

    return p_engine->isTrading&&!lastMd->isInCancelTime();
}


void BaseStrategy::loadPosition() {
    RedisImp r("127.0.0.1");

    auto posJson = r.getRedis().hget("position", this->strategyName);
    if (posJson.has_value()) {
        json tmpJson = json::parse(posJson.value());
        positions = tmpJson.get<std::vector<position>>();
    }

}

void BaseStrategy::savePosition() const {
    RedisImp r("127.0.0.1");
    json positionsJson;
    for (const auto &pos: positions) {
        json posJson;
        to_json(posJson, pos);
        positionsJson.push_back(posJson);
    }
    r.getRedis().hset("position", this->strategyName, positionsJson.dump());
}

void BaseStrategy::start() {
    if (!isActive) {
        SPDLOG_INFO("{} is start now", this->getBaseParams());
        this->loadPosition();
        isActive = true;
        if (jsonParams.contains("dealVol")) {
            dealVol = jsonParams.at("dealVol").get<int>(); // 假设openSS是整数
        }
        if (jsonParams.contains("sumProfit")) {
            sumProfit = jsonParams.at("sumProfit").get<double>(); // 假设openSS是整数
        }
        this->checkDate();
        postStart();
        for(auto & position: positions)
        {
            if(position.getBkVol()==0)
            {
                position.sumBkPrice=0;
            }
            if(position.getSkVol()==0)
            {
                position.sumSkPrice=0;
            }
        }
    }
}

void BaseStrategy::stop() {
    if (isActive) {

        SPDLOG_INFO("{} is stop now", this->strategyName);
        auto it = this->unFinishOrders.begin();
        while (it != this->unFinishOrders.end()) {
            orderCancel(it->second);
            ++it;
        }
        isActive = false;
    } else {
        SPDLOG_INFO("{} was stop now", this->strategyName);
        this->savePosition();
        postStop();
    }
    auto it = this->p_engine->contractMap.find(contractCodes[0]);
    if (it != p_engine->contractMap.end()) {
        this->exchangeId = it->second.at("exchange_id").get<char>();
        this->product_id = it->second.at("product_id").get<string>();
        this->minMove = it->second.at("price_tick").get<double>();
        this->multiple = it->second.at("multiple").get<double>();

        this->trading_time = it->second.at("trading_time").get<short>();
        jsonParams["exchangeId"] = exchangeId;
        jsonParams["minMove"] = minMove;
        jsonParams["multiple"] = multiple;

        jsonParams["trading_time"] = trading_time;
        jsonParams["product_id"] = product_id;
        jsonParams["dealVol"] = dealVol;
        jsonParams["sumProfit"] = sumProfit;
    }
    savePosition();
    saveParams();
    postStop();

}

unsigned int BaseStrategy::getHangingVol(const string &contractCode, unsigned char EES_SideType) {
    unsigned int sum = 0;

    if (!this->unFinishOrders.empty()) {

        for (auto &unFinishOrder: this->unFinishOrders) {
            if (strcmp(contractCode.data(), unFinishOrder.second.contractCode.data()) == 0) {
                if (unFinishOrder.second.side == EES_SideType) {
                    sum = sum + unFinishOrder.second.remainVol;
                }
            }
        }
    }

    return sum;
}

unsigned int BaseStrategy::getSpHangingVol(const string &contractCode) {
    unsigned int sum = 0;

    if (!this->unFinishOrders.empty()) {

        for (auto &unFinishOrder: this->unFinishOrders) {
            if (strcmp(contractCode.data(), unFinishOrder.second.contractCode.data()) == 0) {
                if (unFinishOrder.second.side == EES_SideType_close_ovn_long ||
                    unFinishOrder.second.side == EES_SideType_close_today_long) {
                    sum = sum + unFinishOrder.second.remainVol;
                }
            }
        }
    }
    return sum;
}

unsigned int BaseStrategy::getBpHangingVol(const string &contractCode) {
    unsigned int sum = 0;

    if (!this->unFinishOrders.empty()) {

        for (auto &unFinishOrder: this->unFinishOrders) {
            if (strcmp(contractCode.data(), unFinishOrder.second.contractCode.data()) == 0) {
                if (unFinishOrder.second.side == EES_SideType_close_ovn_short ||
                    unFinishOrder.second.side == EES_SideType_close_today_short) {
                    sum = sum + unFinishOrder.second.remainVol;
                }
            }
        }
    }
    return sum;
}

bool BaseStrategy::isInCloseTime(const TickDataHf &md) {
    if (md.hours == 14 && md.minutes >= 57) {
        return true;
    }
    return false;
}


bool BaseStrategy::isInOpenTime(const TickDataHf &md) {
    int hour = md.hours;
    int minute = md.minutes;
    if ((hour == 9 && minute <= 1) || (hour == 21 && minute <= 1)) {
        return true;
    }
    return false;
}

void BaseStrategy::showParams() const {
    cout << allParams.dump() << endl;
}

void BaseStrategy::saveParams() {

    this->upJsonParams();
    RedisImp redis("127.0.0.1");
    redis.getRedis().hset("strategy", this->strategyName, jsonParams.dump());
}

bool BaseStrategy::isInBeginTime(const TickDataHf &tick) {

    return tick.isInOpenTime();
}
string BaseStrategy::getPositions() const {
    std::ostringstream oss;
    oss << '[';
    try {
        for (size_t i = 0; i < positions.size(); ++i) {
            if (i > 0) {
                oss << ':';
            }
            oss << positions[i].getVol();
        }
    } catch (const std::exception& e) {
        // 处理异常，可以根据实际情况选择日志记录或返回默认值
        return "[]";
    }

    oss << ']';
    return oss.str();
}

void BaseStrategy::upBaseParams() {
    jsonParams["strategyName"] = strategyName;
    jsonParams["contractCodes"] = contractCodes; // 注意：这里只存储了一个contract code的列表或单个code
    jsonParams["openSS"] = openSS;
    jsonParams["minMove"]=minMove;
    jsonParams["multiple"]=multiple;
    jsonParams["openTimes"] = openTimes;
    jsonParams["closeType"] = closeType;
    jsonParams["dealVol"] = dealVol;
    jsonParams["errorId"]=errorId;
    jsonParams["expire"] = expire;
    jsonParams["limitDate"] = limitDate;
    jsonParams["isBeforeLDate"] = isBeforeLDate;
    jsonParams["isActive"] = isActive;
    jsonParams["mdTimes"] = mdTimes;
}

void BaseStrategy::loadBaseParams() {
    if (jsonParams.contains("strategyName")) {
        strategyName = jsonParams.at("strategyName").get<string>();
    }
    if (jsonParams.contains("contractCodes")) {
        contractCodes = jsonParams.at("contractCodes").get<std::vector<string>>();
    }
    if (jsonParams.contains("openSS")) {
        openSS = jsonParams.at("openSS").get<int>(); // 假设openSS是整数
    }
    if (jsonParams.contains("openTimes")) {
        openTimes = jsonParams.at("openTimes").get<int>(); // 假设openSS是整数
    }
    if (jsonParams.contains("dealLimit")) {
        dealLimit = jsonParams.at("dealLimit").get<int>();
    }
    if (jsonParams.contains("limitDate")) {
        limitDate = jsonParams.at("limitDate").get<int>();
    }
    if (jsonParams.contains("dealVol")) {
        dealVol = jsonParams.at("dealVol").get<int>();
    }

}